package net.xiduth.game.player.actions.spells;

import java.util.HashMap;
import java.util.Map;

import net.xiduth.cache.loaders.ItemDefinitions;
import net.xiduth.game.Animation;
import net.xiduth.game.item.Item;
import net.xiduth.game.player.Equipment;
import net.xiduth.game.player.Player;
import net.xiduth.game.player.Skills;
import net.xiduth.game.player.actions.Action;

/**
 * @author Tyluur <ItsTyluur@Gmail.com>
 * @since 2012-07-29
 */
public class BoltEnchantingAction extends Action {

	private static final int AIR_RUNE = 556, WATER_RUNE = 555,
			EARTH_RUNE = 557, FIRE_RUNE = 554, MIND_RUNE = 558,
			NATURE_RUNE = 561, DEATH_RUNE = 560, BLOOD_RUNE = 565,
			SOUL_RUNE = 566, LAW_RUNE = 563, COSMIC_RUNE = 564;

	public enum MagicEnchant {

		OPAL(4, new Item[] { new Item(COSMIC_RUNE), new Item(AIR_RUNE, 2) }, new int[] { 879, 9236}, 14, 9),

		SAPPHIRE(7, new Item[] { new Item(COSMIC_RUNE), new Item(WATER_RUNE), new Item(MIND_RUNE) }, new int[] { 9337, 9240 }, 29, 17),

		JADE(14, new Item[] { new Item(COSMIC_RUNE), new Item(EARTH_RUNE, 2)}, new int[] { 9335, 9237}, 18, 19),

		PEARL(24, new Item[] { new Item(COSMIC_RUNE), new Item(WATER_RUNE, 2) }, new int[] { 880, 9238}, 22, 29),

		EMERALD(27, new Item[] { new Item(COSMIC_RUNE), new Item(AIR_RUNE, 3), new Item(NATURE_RUNE) }, new int[] { 9338, 9241 }, 32, 37),

		RED_TOPAZ(29, new Item[] { new Item(COSMIC_RUNE), new Item(FIRE_RUNE, 2)}, new int[] { 9336, 9239 }, 26, 33),

		RUBY(49, new Item[] { new Item(COSMIC_RUNE), new Item(FIRE_RUNE, 5), new Item(BLOOD_RUNE)}, new int[] { 9339, 9242 }, 35, 59),

		DIAMOND(57, new Item[] { new Item(COSMIC_RUNE), new Item(EARTH_RUNE, 10), new Item(LAW_RUNE, 2)}, new int[] { 9340, 9243}, 38, 67),

		DRAGONSTONE(68, new Item[] { new Item(COSMIC_RUNE), new Item(EARTH_RUNE, 15), new Item(SOUL_RUNE) }, new int[] { 9341, 9244 }, 41, 78),

		ONYX(87, new Item[] { new Item(COSMIC_RUNE), new Item(FIRE_RUNE, 20), new Item(DEATH_RUNE)}, new int[] { 9342, 9245 }, 44, 97);

		private int levelRequired;

		private Item[] runesRequired;

		private int[] items;

		private int buttonId, experience;

		MagicEnchant(int levelRequired, Item[] runesRequired, int[] items, int buttonId, int experience) {
			this.levelRequired = levelRequired;
			this.runesRequired = runesRequired;
			this.items = items;
			this.buttonId = buttonId;
			this.experience = experience;
		}

		private static Map<Integer, MagicEnchant> MAP = new HashMap<Integer, MagicEnchant>();

		static {
			for (MagicEnchant types : MagicEnchant.values()) {
				MAP.put(types.buttonId, types);
			}
		}

		public static MagicEnchant getByButton(int buttonId) {
			return MAP.get(buttonId);
		}

		public int getMagicLevelRequired() {
			return levelRequired;
		}

		public Item[] getRunesRequired() {
			return runesRequired;
		}

		private int[] getItems() {
			return items;
		}

		public int getButtonId() {
			return buttonId;
		}
		
		public int getExperience() {
			return experience;
		}

	}

	private MagicEnchant enchant;

	private final int skill;
	private int amount;

	public BoltEnchantingAction(MagicEnchant enchant, int amount) {
		this.enchant = enchant;
		this.amount = amount;
		skill = Skills.MAGIC;
	}

	private boolean checkAll(Player player) {
		if (amount < 0 || amount == 0) return false;
		for (Item runes : enchant.getRunesRequired()) {
			boolean hasFireRune = player.getInventory().containsItem(FIRE_RUNE,
					1)
					|| (player.getEquipment().getItem(Equipment.SLOT_WEAPON) == null ? false
							: player.getEquipment()
									.getItem(Equipment.SLOT_WEAPON)
									.getDefinitions().getName().toLowerCase()
									.contains("fire"));
			if (runes.getId() == FIRE_RUNE) {
				if (runes.getId() == FIRE_RUNE) continue;
				if (!hasFireRune && !player.getInventory().containsItem(runes.getId(), runes.getAmount())) {
					player.sendMessage("You do not have the correct runes to cast this spell.");
					return false;
				}
			}
			if (!player.getInventory().containsItem(runes.getId(), runes.getAmount())) {
				player.sendMessage("You do not have the correct runes to cast this spell.");
				return false;
			}
		}
		if (player.getSkills().getLevel(skill) < enchant.getMagicLevelRequired()) {
			player.sendMessage("You need a magic level of " + enchant.getMagicLevelRequired() + " to cast this spell.");
			return false;
		}
		if (!player.getInventory().containsItem(enchant.getItems()[0], 10)) {
			player.sendMessage("You do not have a " + ItemDefinitions.forId(enchant.getItems()[0]).getName().toLowerCase() + " to use.");
			return false;
		}
		return true;
	}

	@Override
	public boolean start(Player player) {
		if (!checkAll(player)) return false;
		return true;
	}

	@Override
	public boolean process(Player player) {
		return checkAll(player);
	}

	@Override
	public int processWithDelay(Player player) {
		player.getInterfaceManager().closeScreenInterface();
		player.getInventory().deleteItem(enchant.getItems()[0], 10);
		player.getInventory().addItem(enchant.getItems()[1], 10);
		for (Item item : enchant.getRunesRequired()) {
			player.getInventory().deleteItem(item);
		}
		player.setNextAnimation(new Animation(4462));
		player.getSkills().addXp(skill, enchant.experience);
		player.sendMessage("The magic of the runes coaxes out the true nature of the gem tips.");
		amount--;
		return 3;
	}

	@Override
	public void stop(Player player) {
	}

}
